#ifndef SOCKET_MEMORY_H
#define SOCKET_MEMORY_H

#include "../base/Singleton.hpp"
#include <mutex>

namespace DBServer
{
namespace Socket
{

// MemoryBlock is the minimum element that the tcp buffer use 
// MemoryBlock is the minimum element in a MemoryPage
using MemoryBlock = char;

// MemoryPage
typedef struct MemoryPage {
    char            *page;                  // next page in the memory pool
    char            *cur_block;             // next free block in this page
    int             free_num;
                                            // the num of the free block
    void init();                            // init a memory page and add it into the memory pool
    void release();                         // release a memory page and push it into the memory pool
} MemoryPage;


class MemoryPool : public Base::Singleton<MemoryPool> {
friend class Base::Singleton<MemoryPool>;             // a friend clas which can visit the private element
                                                // that can give a instance for user
public:
    MemoryBlock* New();                      // the interface to malloc for the tcp buffer
    void Delete(MemoryBlock*);              // return the used buffer into the origin page
    ~MemoryPool();
    double get_use_situation();

    MemoryPool(const MemoryPool&) = delete;
    MemoryPool(const MemoryPool&&) = delete;
    MemoryPool operator=(const MemoryPool&&) = delete;
    MemoryPool& operator=(const MemoryPool&) = delete;
private:
    MemoryPool();
    MemoryPage *PoolDilatation();
private:
    MemoryPage**        pages;              // point to a useful page
    int                 page_num;
    long long           use_block;
    int                 using_page;
    std::mutex          op_mtx;
};


} // namespace Scoekt
} // namespace DBServer



#endif